using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Woz
{
    public sealed class DynamicVariables
    {
        /// <summary>
        /// dynamic variables default constructor
        /// </summary>
        private DynamicVariables()
        {
            // initialize the zoom to one hundred percent
            this.mZoom = 1.0f;

            // initialize the transformation matrix
            this.mTransformationMatrix = new Matrix();
            
            // initialize the inverse transformation matrix
            this.mInverseTransformationMatrix = this.mTransformationMatrix.Clone() as Matrix;
            this.mInverseTransformationMatrix.Invert();

            // initialize the consecutive paste
            this.mConsecutivePaste = 1;

            // initialize whether we are using custom transitions in the run screens mode
            this.mUsingCustomTransitions = false;

            // initialize whether we are always performing hittest for strokes
            this.mAlwaysPerformHitTest = true;
        }

        /// <summary>
        /// the single instance of this class
        /// </summary>
        public static DynamicVariables Instance
        {
            get
            {
                // if an instance doesnt exist create it
                if (sInstance == null)
                {
                    sInstance = new DynamicVariables();
                }

                // return the instance
                return sInstance;
            }
        }

        /// <summary>
        /// gets or sets the magnification of the canvas
        /// </summary>
        public float Zoom
        {
            get
            {
                return this.mZoom;
            }

            set
            {
                // clamp the zoom between ten percent and four hundred percent
                this.mZoom = Math.Max(0.10f, Math.Min(4.0f, value));
            }
        }

        /// <summary>
        /// gets or sets the transformation matrix
        /// </summary>
        public Matrix TransformationMatrix
        {
            get
            {
                return this.mTransformationMatrix;
            }
            set
            {
                // save the transformation matrix
                this.mTransformationMatrix = value;

                // save its inverse
                this.mInverseTransformationMatrix = value.Clone() as Matrix;
                this.mInverseTransformationMatrix.Invert();
            }
        }

        /// <summary>
        /// gets the inverse of the transformation matrix
        /// </summary>
        public Matrix InverseTransformationMatrix
        {
            get
            {
                return this.mInverseTransformationMatrix;
            }
        }

        /// <summary>
        /// gets or sets the number of consecutive paste operations
        /// </summary>
        public int ConsecutivePaste
        {
            get
            {
                return this.mConsecutivePaste;
            }
            set
            {
                this.mConsecutivePaste = Math.Max(1, value);
            }
        }

        /// <summary>
        /// gets or sets whether we are using custom transitions in the run screens mode
        /// </summary>
        public bool UsingCustomTransitions
        {
            get
            {
                return this.mUsingCustomTransitions;
            }
            set
            {
                this.mUsingCustomTransitions = value;
            }
        }

        /// <summary>
        /// gets or sets whether we are always performing hittest for strokes
        /// </summary>
        public bool AlwaysPerformHitTest
        {
            get
            {
                return this.mAlwaysPerformHitTest;
            }
            set
            {
                this.mAlwaysPerformHitTest = value;
            }
        }

        /// <summary>
        /// the single instance of this class
        /// </summary>
        private static DynamicVariables sInstance;

        /// <summary>
        /// the magnification of the canvas
        /// </summary>
        private float mZoom;

        /// <summary>
        /// the transformation matrix used by the canvas and all the tools
        /// </summary>
        private Matrix mTransformationMatrix;

        /// <summary>
        /// the inverse transformation matrix used by the canvas and all the tools
        /// </summary>
        private Matrix mInverseTransformationMatrix;

        /// <summary>
        /// the number of consecutive paste operations
        /// </summary>
        private int mConsecutivePaste;

        /// <summary>
        /// indicates whether we are using custom transitions in the run screens mode
        /// </summary>
        private bool mUsingCustomTransitions;

        /// <summary>
        /// indicates whether we are always performing hittest for strokes
        /// </summary>
        private bool mAlwaysPerformHitTest;
    }
}
